<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="coinfaces">

        <title>Docker容器中的init进程</title>

    <link rel="stylesheet" href="../theme/css/style.css">
    <link rel="stylesheet" href="../theme/css/pygments.css">



</head>

<body>
    <div class="content">
<h1>Docker容器中的init进程</h1>    <p>
        under
    </p>
    <p>
        in <a href="../categories/draft/">draft</a>
    </p>
    <p>Published: 2020-02-27</p>


    <p>在Docker容器中，如果有多个进程在运行，它们会形成一个以PID=1（因为Docker容器中PID独立于宿主机中的PID，同一个进程在Docker容器中和宿主机中查询到的PID是不一样的）的进程为根的进程树，并且其承担的角色和和宿主机的init进程类似，但如果用户指定了不合适的程序作为容器的init进程就可能引起问题。</p>
<p>容器中的init进程需要实现3个功能：</p>
<ol>
<li>启动需要在容器中运行的所有应用程序</li>
</ol>
<p>这是必备条件，否则容器不能正常履行其职责。</p>
<ol>
<li>将用户终止容器运行时通知其它应用程序退出</li>
</ol>
<p>当用户输入<code>docker stop</code>来终止容器运行时，docker会向容器的init进程发送SIGTERM信号，但是Linux系统中PID=1的进程没有默认的信号处理函数，也就是说，如果这个进程没有处理SIGTERM信号的逻辑，进程不会终止，经过一段时间后，docker发现容器的init进程还在运行，便会发送SIGKILL信号杀死这个进程，这个进程退出后，容器中所有其它进程也会被SIGKILL信号强行终止运行。为避免这种情况发生，init进程必须向子进程转发SIGTERM信号，并在其所有子进程都退出后才终止运行。</p>
<ol>
<li>对系统中在父进程退出之后退出的进程执行<code>wait</code>系统调用（即reap）</li>
</ol>
<p>退出后但没有其它进程对其执行<code>wait</code>系统调用的进程叫僵尸进程，不应该长期存在于系统中。如果容器中的init进程没有reap功能，会增大容器中僵尸进程累积，耗尽容器内（容器中进程数量受限，如使用了<code>--pids-limit</code>参数）甚至宿主系统中进程表资源的风险。</p>
<p>为确保容器中的init进程实现了第2、3项功能，建议在运行docker的时候加上<code>--init</code>参数，如果使用的docker版本还不支持这个参数，可以用<a href="https://github.com/krallin/tini">tini</a>作为容器的init进程。</p>
<p>常见但不太合适作为init进程运行的程序：</p>
<ul>
<li>Bash，</li>
</ul>
<p>它具有reap功能，但是用<code>docker stop</code>终止容器运行时，bash进程会先于其它进程退出，导致其它应用程序被SIGKILL信号强制终止运行</p>
<ul>
<li>Supervisord</li>
</ul>
<p>它收到SIGTERM信号后会通知并等待其监管的任务退出，甚至也<a href="https://github.com/Supervisor/supervisor/blob/3.3.1/supervisor/supervisord.py#L285">实现了reap功能</a>，但不确保多个程序同时退出时能正常工作。如果它reap了非自己监管的进程，会抱怨，并且其<a href="https://github.com/Supervisor/supervisor/blob/3.3.1/docs/index.rst">文档</a>明确其目的不是作为init进程来运行。</p>
    </div>
<nav class="nav sidebar">
    <div class="siteinfo">
        <div class="sitename"><a href="..">coinfaces</a></div>
        <div class="tagline">Another Side of Life</div>
    </div>

        <a href="../categories/">categories</a>
        <a href="..">&larr; Home</a>
</nav><footer class="footer">
    <span>
        &copy; jpli &middot;
        under <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">CC-BY-SA 4.0</a>
    </span>
    |
    <span>
        Powered by:
        <a href="http://blog.getpelican.com/">Pelican</a>
    </span>
</footer></body>
</html>